﻿using System;
using System.Management;
using ClusterAwareProperties;
using ClusterAwareProperties.Properties;

namespace ClusterAwareProperties
{
    /// <summary>
    /// Wrapper class ResourceType ManagementObject
    /// </summary>
    public class ResourceTypeProperty : IDisposable
    {

        #region private property

        private readonly ManagementObject _classInstance;

        #endregion

        #region ctor

        ///<summary>
        /// Constructor
        ///</summary>
        private ResourceTypeProperty()
        {
            Status = StatusResource.Unknown;
            Characteristics = CharacteristisResourceType.Unknown;
        }

        ///<summary>
        /// Constructor
        ///</summary>
        ///<param name="queryobj">Resorucetype ManagementObject instance</param>
        public ResourceTypeProperty(ManagementObject queryobj)
            : this()
        {
            var path = queryobj.ToString();
            if (path.IndexOf("\\root\\MSCluster:MSCluster_ResourceType") == -1)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_TypeClassInvalid, path, "\\root\\MSCluster:MSCluster_ResourceType"));
            }
            _classInstance = queryobj;
            this.Convert(queryobj);
        }

        #endregion

        #region public properties

        /// <summary>
        /// Return instance of Resource ManagementObject
        /// </summary>
        public ManagementObject Instance
        {
            get { return _classInstance; }
        }

        /// <summary>
        /// Provides a short textual description of the resource type.
        /// </summary>
        public string Caption { get; internal set; }

        /// <summary>
        /// Indicates when the resource type was installed. A lack of a value does not indicate that the resource type is not installed.
        /// </summary>
        public DateTime? InstallDate { get; internal set; }

        /// <summary>
        /// Indicates the current status of the resource type.
        /// </summary>
        public StatusResource Status { get; internal set; }

        /// <summary>
        /// Provides access to the flags set for the resource type. For a list of possible characteristics, see CLUSCTL_RESOURCE_TYPE_GET_FLAGS.
        /// </summary>
        public UInt32 Flags { get; set; }

        /// <summary>
        /// Provides access to the characteristics set for the resource type. For a list of possible characteristics, see CLUSCTL_RESOURCE_TYPE_GET_CHARACTERISTICS..
        /// </summary>
        public CharacteristisResourceType Characteristics { get; set; }

        /// <summary>
        /// Provides the name of the resource type.
        /// </summary>
        public string Name { get; internal set; }

        /// <summary>
        /// Provides access to the resource type's Name property, which is the name displayed for the resource type.
        /// </summary>
        public string DisplayName { get; set; }

        /// <summary>
        /// Provides access to the resource type's Description property.
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// Provides the class identifiers (CLSIDs) for the Cluster Administrator extension DLLs that are associated with the resource type.
        /// </summary>
        public string[] AdminExtensions { get; set; }

        /// <summary>
        /// Provides access to the resource type's DllName property, which is the name of the dynamic-link library (DLL) for the resource type.
        /// </summary>
        public string DllName { get; internal set; }

        /// <summary>
        /// Provides access to the resource type's IsAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it is operational.
        /// </summary>
        public UInt32 IsAlivePollInterval { get; set; }

        /// <summary>
        /// Provides access to the resource type's LooksAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it appears operational.
        /// </summary>
        public UInt32 LooksAlivePollInterval { get; set; }

        /// <summary>
        /// The resource can be selected as the quorum resource for the cluster.
        /// </summary>
        public bool QuorumCapable { get; set; }

        /// <summary>
        /// The resource can be selected as the quorum resource in clusters configured using the -localquorum switch.
        /// </summary>
        /// <remarks>
        /// This property is not supported in Windows 2008.
        /// </remarks>
        public bool? LocalQuorumCapable { get; set; }

        /// <summary>
        /// The resource cannot be deleted unless all nodes are active.
        /// </summary>
        public bool DeleteRequiresAllNodes { get; internal set; }

        /// <summary>
        /// The length of time to wait, in milliseconds, before declaring a deadlock in any call into a resource.
        /// </summary>
        /// <remarks>
        /// This property is not supported in Windows 2008.
        /// </remarks>
        public UInt32? DeadlockTimeout { get; set; }

        /// <summary>
        /// If a resource cannot be brought online or taken offline in the number of milliseconds specified by this property, the resource is forcibly terminated.
        /// </summary>
        /// <remarks>
        /// This property is not supported in Windows 2003
        /// </remarks>
        public UInt32? PendingTimeout { get; set; }

        /// <summary>
        /// Private properties of the resource type.
        /// </summary>
        /// <remarks>
        /// This property is not supported in Windows 2003
        /// </remarks>
        public PrivatePropertiesData PrivateProperties { get; set; }

        #endregion

        #region IDisposable Members

        /// <summary>
        /// Dispose Class
        /// </summary>
        public void Dispose()
        {
            if (Instance != null)
            {
                Instance.Dispose();
            }

        #endregion
        }
    }
}
